package cn.xsly.ymcc.service.impl;

import cn.xsly.ymcc.constants.MQConstants;
import cn.xsly.ymcc.doc.CourseDoc;
import cn.xsly.ymcc.domain.*;
import cn.xsly.ymcc.dto.*;
import cn.xsly.ymcc.fegin.MediaFeginClient;
import cn.xsly.ymcc.fegin.SearchFeginClient;
import cn.xsly.ymcc.mapper.CourseMapper;
import cn.xsly.ymcc.mapper.TeacherMapper;
import cn.xsly.ymcc.result.JSONResult;
import cn.xsly.ymcc.service.*;
import cn.xsly.ymcc.util.AssertUtil;
import cn.xsly.ymcc.util.StrUtils;
import cn.xsly.ymcc.vo.CourseDetailVo;
import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import springfox.documentation.spring.web.json.Json;


import javax.management.Query;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author whale
 * @since 2022-10-23
 */
@Service
@Slf4j
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {
    @Autowired
    private ICourseDetailService detailService;
    @Autowired
    private ICourseMarketService marketService;
    @Autowired
    private ICourseResourceService resourceService;
    @Autowired
    private ICourseTeacherService courseTeacherService;
    @Autowired
    private TeacherMapper teacherMapper;
    @Autowired
    private ICourseMarketService courseMarketService;
    @Autowired
    private ICourseSummaryService courseSummaryService;
    @Autowired
    private SearchFeginClient searchFeginClient;
    @Autowired
    private ICourseDetailService courseDetailService;
    @Autowired
    private ITeacherService teacherService;
    @Autowired
    private ICourseChapterService courseChapterService;
    @Autowired
    private MediaFeginClient mediaFeginClient;
    @Autowired
    private ICourseUserLearnService courseUserLearnService;


    @Override
    public void save(CourseParamDto dto) {
        Course course = dto.getCourse();
        CourseDetail courseDetail = dto.getCourseDetail();
        CourseMarket courseMarket = dto.getCourseMarket();
        CourseResource courseResource = dto.getCourseResource();
        List<Long> teacherIds = dto.getTeacherIds();
        //保存课程表
        course.setStatus(Course.STATUS_OFFLINE);
        //TODO
        course.setLoginId(1L);
        course.setLoginUserName("zs");
        //老师名字查询
        Wrapper<Teacher> query = new EntityWrapper<>();
        // where  id  in （ 1,2）
        query.in("id", teacherIds);
        List<Teacher> teachers = teacherService.selectList(query);

        String teacherNames = teachers.stream().map(teacher -> teacher.getName()).collect(Collectors.joining(","));
        course.setTeacherNames(teacherNames);
        insert(course);
        //保存详情表
        courseDetail.setId(course.getId());
        detailService.insert(courseDetail);
        //4.保存营销表
        courseMarket.setId(course.getId());
        marketService.insert(courseMarket);
        //保存资源表
        courseResource.setCourseId(course.getId());
        resourceService.insert(courseResource);
        //7.初始化汇总表
        CourseSummary courseSummary = new CourseSummary();
        courseSummary.setId(course.getId());
        courseSummaryService.insert(courseSummary);

        //保存老师中间表
        teacherIds.forEach(teacherId -> {
            CourseTeacher courseTeacher = new CourseTeacher();
            courseTeacher.setCourseId(course.getId());
            courseTeacher.setTeacherId(teacherId);
            courseTeacherService.insert(courseTeacher);
        });
    }

    //检验，修改课程字段，上线时间，状态，保存es里面，在做站内信发消息
    @Override
    public void onLineCourse(Long id) {
        Course course = selectById(id);
        AssertUtil.isNotNull(course, "课程不能为空");
        CourseMarket courseMarket = courseMarketService.selectById(id);
        CourseSummary courseSummary = courseSummaryService.selectById(id);
        course.setStatus(1);
        course.setOnlineTime(new Date());
        updateById(course);
        CourseDoc doc = new CourseDoc();
        courseMarketService.updateById(courseMarket);
        doc.setChargeName(courseMarket.getCharge() == 1 ? "免费" : "收费");
        courseSummaryService.updateById(courseSummary);
        BeanUtils.copyProperties(course, doc);
        BeanUtils.copyProperties(courseMarket, doc);
        BeanUtils.copyProperties(courseSummary, doc);
        searchFeginClient.save(doc);

        SendStationMsg(doc);

    }

    @Override
    public void offLineCourse(Long id) {
        Course course = selectById(id);
        AssertUtil.isNotNull(course, "课程不能为空");
        CourseMarket courseMarket = courseMarketService.selectById(id);
        CourseSummary courseSummary = courseSummaryService.selectById(id);
        course.setStatus(0);
        updateById(course);
        CourseDoc doc = new CourseDoc();
        courseMarketService.updateById(courseMarket);
        courseSummaryService.updateById(courseSummary);
        BeanUtils.copyProperties(course, doc);
        BeanUtils.copyProperties(courseMarket, doc);
        BeanUtils.copyProperties(courseSummary, doc);
        searchFeginClient.delete(doc);


    }

    @Override
    public CourseDetailVo courseDetailById(Long id) {
        // 1.数据的验证  id
        AssertUtil.isNotNull(id, "非法的请求");
        //2.根据id查询Course
        Course course = selectById(id);
        // 3.验证课程状态数据是否存在
        AssertUtil.isNotNull(course, "课程不存在");
        AssertUtil.isEqualsTrim(course.getStatus(), Course.STATUS_ONLINE, "课程未上架");
        // 4.查询营销数据CourseMarket
        CourseMarket courseMarket = marketService.selectById(id);
        // 5.查询课程详情
        CourseDetail courseDetail = detailService.selectById(id);
        // 6.查询课程对应的老师【根据课程id找中间表，根据中间表找Teacher表】
        /*
            select t.* from t_course_teachet ct inner join t_teacher t on ct.teacher_id = t.id where ct.course_id =#{id}
         */
        List<Teacher> teachers = selectTeacherByCourseId(id);
        List<CourseChapter> courseChapters = selectChapter(id);

        return new CourseDetailVo(course, courseMarket, courseDetail, teachers, courseChapters);

    }

    private List<Teacher> selectTeacherByCourseId(Long id) {
        Wrapper<CourseTeacher> wrapper = new EntityWrapper<>();
        wrapper.eq("course_id", id);
        List<CourseTeacher> courseTeachers = courseTeacherService.selectList(wrapper);
        //获取集合里面所有的老师的id
        List<Long> teacherIds = courseTeachers.stream().map(CourseTeacher::getTeacherId).collect(Collectors.toList());
        List<Teacher> teachers = teacherService.selectBatchIds(teacherIds);
        return teachers;
    }

    private List<CourseChapter> selectChapter(Long id) {
        /*7.根据课程找对应的章节
        7.1 找到对应的媒体数据【根据课程查-->List 就是本课程下面所有的媒体数据】
        7.2 把所有的章节转换为 map<id，章节自己>
                7.3 循环变量媒体的list-->媒体数据找到自己所属的章节，添加进去
                [排序要么交给前端，要么自己写]
         */
        //7.根据课程找对应的章节
        Wrapper<CourseChapter> wrapper = new EntityWrapper<>();
        wrapper.eq("course_id", id);
        List<CourseChapter> courseChapters = courseChapterService.selectList(wrapper);
        //7.2 把所有的章节转换为 map<id，章节自己>
        Map<Long, CourseChapter> chapterMap = courseChapters.stream().collect(Collectors.toMap(CourseChapter::getId, CourseChapter -> CourseChapter));

        // 7.1 找到对应的媒体数据【根据课程查-->List 就是本课程下面所有的媒体数据】
        JSONResult jsonResult = mediaFeginClient.selectByCourseId(id);
        AssertUtil.isTrue(jsonResult.isSuccess(), jsonResult.getMessage());

        String jsonString = JSON.toJSONString(jsonResult.getData());
        List<MediaFile> mediaFiles = JSON.parseArray(jsonString, MediaFile.class);

        mediaFiles.forEach(mediaFile -> {
            //清空视频播放地址
            //mediaFile.setFileUrl("");
            CourseChapter courseChapter = chapterMap.get(mediaFile.getChapterId());
            if (courseChapter != null) courseChapter.getMediaFiles().add(mediaFile);
        });

        return courseChapters;
    }

    @Override
    public CourseStateVo courseStateById(Long id) {
        AssertUtil.isNotNull(id, "非法的请求");
        //1.查询Course表 检查课程状态
        Course course = selectById(id);
        //2.查询营销表 课程是否免费
        CourseMarket courseMarket = marketService.selectById(id);
        //3.要用户是否购买的此课程
        //3.1 获取当前的登录用户
        Long loginId = 3L;

        Wrapper<CourseUserLearn> wrapper = new EntityWrapper<>();
        wrapper.eq("login_id", loginId);
        wrapper.eq("course_id", id);
        CourseUserLearn courseUserLearn = courseUserLearnService.selectOne(wrapper);
        //检查课程是否上线
        boolean isOnline = course.getStatus() == Course.STATUS_ONLINE;
        //检查课程是否免费
        boolean isFree = courseMarket.getCharge() == 1;
        //用户是否购买
        boolean isBuy = courseUserLearn != null && courseUserLearn.getState() != 1;

        return new CourseStateVo(isFree, isOnline, isBuy);
    }

    @Override
    public CourseOrderVo orderList(String ids) {
        //1.对于请求的数据进行校验
        //2.对数据进行分割处理
        //3.去course表里面找出所有的id对应Course
        //4.去market表里面找到所有的id对应CourseMarket
        //5.数据封装为CourseItemVo--->添加到- - 个list
        //6.计算所有的课程的总金额。

        AssertUtil.isNotNull(ids,"课程订单不存在");
        List<Long> courseIds = StrUtils.splitStr2LongArr(ids);
        List<Course> courses = selectBatchIds(courseIds);
        List<CourseMarket> courseMarkets = courseMarketService.selectBatchIds(courseIds);
        //集合转map
        Map<Long, CourseMarket> marketMap = courseMarkets.stream().collect(Collectors.toMap(CourseMarket::getId, CourseMarket -> CourseMarket));

        List<CourseItemVo> courseItemVos=new ArrayList<>();

        BigDecimal totalAmount= BigDecimal.valueOf(0);
        for(Course course:courses){
            CourseMarket courseMarket = marketMap.get(course.getId());
            courseItemVos.add(new CourseItemVo(course,courseMarket));
             totalAmount = totalAmount.add(courseMarket.getPrice());
        }

        CourseOrderVo courseOrderVo = new CourseOrderVo(courseItemVos,totalAmount);

        return courseOrderVo;
    }


    @Autowired
    private RocketMQTemplate rocketMQTemplate;


    public void SendStationMsg(CourseDoc doc) {

        List<Long> ids = Arrays.asList(1l, 2l);
        String content = "亲爱的用户您好，最新课程  <a href='http://course.ymcc.com:6002/detail.html?courseId=%s'> %s </a> 发布啦，点击课程了解详情";
        String format = String.format(content, doc.getId(), doc.getName());
        StationMessageDto stationMessageDto = new StationMessageDto("课程发布了", format, "系统消息", ids);
        String jsonString = JSON.toJSONString(stationMessageDto);
        Message<String> message = MessageBuilder.withPayload(jsonString).build();
        SendResult sendResult = rocketMQTemplate.syncSend(MQConstants.TOPIC_STATION_MESSAGE + ":" + MQConstants.TAGS_STATION_MESSAGE, message);

        log.info("站内信保存完成", sendResult);
    }

}
